﻿/*
 * masterdm.h
 *
 *  Created on: 2017年5月17日
 *      Author: work
 */

#ifndef APPS_DMSYNC_INC_MASTERDM_H_
#define APPS_DMSYNC_INC_MASTERDM_H_

#include <dm/os/protocol/protocolmaster.hpp>
#include "framedm.h"
#include <dm/scada/deviceagent.hpp>

/**
 * DM同步主站规约
 */
class CMasterDm:public dm::os::protocol::CProtocolMaster{
public:
	/**
	 * 召唤数据的步骤
	 */
	enum ECallStep{
		CSStatus,  //!< 召唤状态量
		CSDiscrete,//!< 召唤离散量
		CSMeasure, //!< 召唤测量量
		CSCumulant //!< CSCumulant
	};

	CMasterDm();
	~CMasterDm();

	const char* name()const;

	frame_t& getRxFrame();
	const frame_t& getTxFrame();

	bool setStatusOffset( int offset );
	bool setStatusSize( int size );

	bool setDiscreteOffset( int offset );
	bool setDiscreteSize( int size );

	bool setMeasureOffset( int offset );
	bool setMeasureSize( int size );

	bool setCumulantOffset( int offset );
	bool setCumulantSize( int size );

	bool setRmtctlOffset( int offset );
	bool setRmtctlSize( int size );

	bool setParameterOffset( int offset );
	bool setParameterSize( int size );

	bool setActionOffset( int offset );
	bool setActionSize( int size );

	inline void setCallInterval( int v ){
		m_callInterval = v;
	}

	inline void setWaitTimeout( unsigned int sec ){
		m_waitTimeout = sec;
	}

	inline void setSendInterval( unsigned int msec ){
		m_sendInterval = msec;
	}

	void reset( const ts_t& ts,const rts_t& rts );

	EAction dealRxFrame( const ts_t& ts,const rts_t& rts );

	inline void setClockInterval( unsigned int s ){
		m_clockInterval = s;
	}

	inline const unsigned int& getClockInterval()const{
		return m_clockInterval;
	}

	inline void setAcceptClock( bool a=true ){
		m_acceptClock = a;
	}

	inline const bool& ifAcceptClock()const{
		return m_acceptClock;
	}

protected:
	EAction taskStart_call( const ts_t& ts,const rts_t& rts );
	EAction taskDo_call( const ts_t& ts,const rts_t& rts );

	EAction task_none( const ts_t& ts,const rts_t& rts );

	EAction onMsgRequest_syncClock( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );
	EAction onMsgRequest_call( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );
	EAction onMsgRequest_rmtCtl( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );
	EAction onMsgRequest_set( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );
	EAction onMsgRequest_get( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );
	EAction onMsgRequest_syncData( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );
	EAction onMsgRequest_remoteReset( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );

	EAction onMsgAnswer_update( dm::os::msg::CMsgInfo& msg,const ts_t& ts,const rts_t& rts );

protected:
	CFrameDm m_rxFrame;
	CFrameDm m_txFrame;

	ECallStep m_callStep;	// 召唤步骤
	
	int m_callIndex;		// 召唤索引号
	int m_callInterval;		// 召唤间隔

	int m_offset_s;			// 状态量偏移
	int m_size_s;			// 状态量数量

	int m_offset_d;			// 离散量偏移
	int m_size_d;			// 离散量数量

	int m_offset_m;			// 测量量偏移
	int m_size_m;			// 测量量数量

	int m_offset_c;			// 累计量偏移
	int m_size_c;			// 累计量数量

	int m_offset_r;			// 远控偏移
	int m_size_r;			// 远控数量

	int m_offset_p;			// 参数偏移
	int m_size_p;			// 参数数量

	int m_offset_a;			// 动作偏移
	int m_size_a;			// 动作数量

	unsigned int m_sendInterval;	// 发送间隔：秒

	dm::CRunTimeStamp m_lastClock;		// 上次发送对时时刻
	unsigned int m_clockInterval;	// 发送对时命令间隔：秒

	bool m_acceptClock;				// 是否接受对端对时
};

#endif /* APPS_DMSYNC_INC_MASTERDM_H_ */
